<template>
  <!-- 外层替换为 Element Dialog 组件 -->
  <el-dialog
    :visible.sync="dialogVisible"
    :title="dialogTitle"
    :width="dialogWidth"
    :show-close="true"
    :close-on-click-modal="false"
    :before-close="handleBeforeClose"
    class="file-upload-confirmation-dialog"
    aria-modal="true"
  >
    <!-- Dialog 内容区 -->
    <div class="dialog-content">
      <!-- 个人信息（多用户切换） -->
      <div class="personal-info" v-if="fileData.length">
        <span class="user-index">({{ currentIndex + 1 }}/{{ fileData.length }})</span>
        <span class="user-id">{{ fileData[currentIndex] && fileData[currentIndex].name || '' }}</span>
      </div>

      <!-- 档案预览区域 -->
      <div class="file-preview" v-if="fileData.length">
        <div class="file-item">
          <div class="file-content-with-actions">
            <div class="file-content">
              <!-- 循环当前用户的文件列表 -->
              <div
                class="preview-container"
                v-for="(file, fileIdx) in currentFiles"
                :key="file.uniqueId"
                :data-file-id="file.uniqueId"
                :class="{ 'selected': fileData[currentIndex] && fileData[currentIndex].highlightedIdx === fileIdx, 'duplicate-url': file.hasDuplicateUrl }"
              >
                <!-- 调试信息 -->
                <div class="debug-info" v-if="debugMode">
                  <span class="duplicate-warning" v-if="file.hasDuplicateUrl">⚠️ 检测到重复URL</span>
                </div>

                <!-- 单个文件预览区 -->
                <div class="file-preview-area" :class="{ 'second-file': currentIndex !== 0 }">
                  <div class="single-preview-item">
                    <!-- 文件预览/上传触发区 -->
                    <div
                      class="preview-media"
                      @click.stop="file.url ? handlePreviewImg(file.url) : triggerSingleUpload(fileIdx)"
                    >
                      <!-- 有文件时显示预览 -->
                      <template v-if="file.url && file.url.trim()">
                        <!-- 图片加载中 -->
                        <div class="preview-loading" v-if="isImage(file.url) && !imageLoaded[file.uniqueId]">
                          <i class="el-icon-loading el-icon--loading"></i>
                          <p class="loading-tip">加载中...</p>
                        </div>

                        <!-- 图片预览 -->
                        <img
                          v-if="isImage(file.url)"
                          :src="file.url"
                          :alt="`档案图片 ${fileIdx + 1}`"
                          class="preview-img"
                          @error="handleImageError(file.uniqueId)"
                          @load="handleImageLoad(file.uniqueId)"
                          :style="{ display: imageLoaded[file.uniqueId] ? 'block' : 'none' }"
                        >
                        <!-- 文档预览 -->
                        <div v-else class="doc-preview">
                          <i class="el-icon-document doc-icon"></i>
                          <div class="doc-info">
                            <span class="doc-name">{{ getFileName(file.name) }}</span>
                            <span class="doc-ext">.{{ getFileExtension(file.url) }}</span>
                          </div>
                        </div>
                      </template>

                      <!-- 无文件时显示上传提示 -->
                      <template v-else>
                        <div class="empty-preview">
                          <i class="el-icon-upload upload-icon"></i>
                          <p class="empty-tip">点击上传文件</p>
                          <p class="empty-subtip">支持jpg/png/pdf/doc等格式</p>
                        </div>
                      </template>
                    </div>

                    <!-- 操作按钮 -->
                    <div class="single-file-actions" v-if="file.url && file.url.trim()">
                      <button
                        class="btn small-btn delete-single-btn"
                        @click.stop="handleDeleteSingle(fileIdx)"
                        title="删除此文件"
                        aria-label="删除文件"
                      >
                        <i class="el-icon-delete"></i>
                      </button>
                      <button
                        class="btn small-btn replace-single-btn"
                        @click.stop="handleReplaceSingle(fileIdx)"
                        title="替换此文件"
                        aria-label="替换文件"
                      >
                        <i class="el-icon-refresh"></i>
                      </button>
                    </div>
                  </div>
                </div>

                <!-- 文件类型选择 -->
                <div class="type-radio-container" :class="{ 'disabled': !file.url || !file.url.trim() }">
                  <p class="radio-group-title">为第{{ fileIdx + 1 }}个文件选择类型：</p>
                  <div class="type-radio-group">
                    <label
                      class="radio-label"
                      v-for="(typeName, typeKey) in fileTypeMap"
                      :key="typeKey"
                      :class="{
                        'selected': file.type === typeKey,
                        'disabled': (!file.url || !file.url.trim()) || isTypeUsed(typeKey, fileIdx)
                      }"
                      @click="(file.url && file.url.trim()) && handleTypeSelect(fileIdx, typeKey)"
                    >
                      <input
                        type="radio"
                        :value="typeKey"
                        :checked="file.type === typeKey"
                        :disabled="(!file.url || !file.url.trim()) || isTypeUsed(typeKey, fileIdx)"
                        class="radio-input"
                      >
                      <span class="radio-text">{{ typeName }}</span>
                    </label>
                  </div>
                </div>
              </div>

              <!-- 隐藏的上传组件 -->
              <file-upload
                :ref="`fileUpload${currentIndex}`"
                :action="uploadAction"
                :file-type="['jpg','jpeg','png','pdf','doc','docx']"
                :file-size="10"
                :value="listToString(currentFiles, currentIndex)"
                @input="(val) => handleFileChange(val, currentIndex, replaceFileIdx)"
                @on-success="() => handleUploadSuccess(currentIndex)"
                :disabled="false"
                :is-show-tip="false"
                class="hidden-upload"
              />
            </div>
          </div>
        </div>
      </div>

      <!-- 档案缺失情况 -->
      <div class="missing-files" v-if="fileData.length">
        <h4 class="missing-title">未选择的档案类型</h4>
        <div class="missing-checkboxes">
          <label
            class="file-checkbox"
            v-for="(typeName, typeKey) in fileTypeMap"
            :key="typeKey"
          >
            <input
              type="checkbox"
              :checked="missingFiles[typeKey]"
              disabled
              class="checkbox-input"
            >
            <span class="checkbox-text" :class="{ 'missing-tag': missingFiles[typeKey] }">
              {{ typeName }}
              <span v-if="missingFiles[typeKey]" class="missing-text">(未选择)</span>
            </span>
          </label>
        </div>
      </div>

      <!-- 备注区域 -->
      <div class="remarks" v-if="fileData.length">
        <label class="remarks-label" for="remarksInput">备注</label>
        <textarea
          id="remarksInput"
          v-model="currentRemark"
          class="remarks-input"
          placeholder="请输入备注信息（如特殊档案说明）..."
          rows="3"
        ></textarea>
      </div>
    </div>

    <!-- Dialog 底部按钮 -->
    <template #footer>
      <div class="dialog-footer-actions">
        <button
          class="btn prev-btn"
          @click="handlePrev"
          :disabled="currentIndex === 0 || !fileData.length"
          aria-label="上一位用户"
        >
          <i class="el-icon-arrow-left"></i> 上一位
        </button>
        <button
          class="btn next-btn"
          @click="handleNext"
          :disabled="currentIndex === fileData.length - 1 || !fileData.length"
          aria-label="下一位用户"
        >
          下一位 <i class="el-icon-arrow-right"></i>
        </button>
        <button class="btn cancel-btn" @click="handleBeforeClose" aria-label="取消">取消</button>
        <button
        class="btn confirm-btn"
        @click="handleSingleConfirm(currentIndex)"
        :disabled="hasDuplicateUrls"
        aria-label="提交当前用户档案">
        提交用户ID【{{ fileData[currentIndex] && fileData[currentIndex].id || '' }}】的档案
        </button>
        <button
          class="btn confirm-btn"
          @click="onConfirm"
          :disabled="hasDuplicateUrls"
          aria-label="确认提交全部"
        >
          确认提交全部
        </button>
      </div>
    </template>

    <!-- 图片放大预览弹窗 -->
    <el-dialog
      :visible.sync="previewVisible"
      width="80%"
      title="档案图片预览"
      :close-on-click-modal="true"
      :show-close="true"
      class="preview-dialog"
      append-to-body
    >
      <div class="preview-modal-content">
        <img :src="previewImg" alt="放大预览图" class="preview-modal-img">
      </div>
    </el-dialog>

    <!-- URL重复提示弹窗 -->
    <el-dialog
      :visible.sync="duplicateUrlDialogVisible"
      width="500px"
      title="警告：检测到重复文件URL"
      :close-on-click-modal="false"
      :show-close="true"
      class="duplicate-dialog"
      append-to-body
    >
      <div class="duplicate-url-message">
        <p class="message-line">检测到多个文件使用了相同的URL，这会导致显示相同的内容。</p>
        <p class="message-line">建议操作：</p>
        <ul class="message-list">
          <li class="list-item">1. 请删除重复的文件并重新上传</li>
          <li class="list-item">2. 确保每次上传的是不同的文件</li>
          <li class="list-item">3. 如问题持续，请联系系统管理员</li>
        </ul>
      </div>
      <div slot="footer" class="dialog-footer">
        <button class="btn confirm-btn" @click="duplicateUrlDialogVisible = false">我知道了</button>
      </div>
    </el-dialog>
  </el-dialog>
</template>

<script>
import FileUpload from '@/components/FileUpload/index.vue';
import { getToken } from "@/utils/auth";

export default {
  name: 'FileUploadConfirmationDialog',
  components: { FileUpload },
  props: {
    registrationId: {
      type: String,
      required: true,
      default: ""
    },
    visible: {
      type: Boolean,
      required: true,
      default: false
    },
    userData: {
      type: Array,
      required: true,
      // 组件内部的验证规则
      validator: (value) => {
        return value.every(item =>
          item.id && typeof item.id === 'number' &&  // id必须存在且为数字
          typeof item.remark === 'string' &&         // remark必须为字符串
          Array.isArray(item.urls) &&                // urls必须是数组
          Array.isArray(item.fileTypes) &&           // fileTypes必须是数组
          item.urls.length === item.fileTypes.length // urls和fileTypes长度必须一致
        );
      },
      default: () => []
    },
    dialogTitle: {
      type: String,
      default: '上传档案确认'
    },
    dialogWidth: {
      type: String,
      default: '90%'
    }
  },
  data() {
    return {
      uploadAction: "/file/upload",
      fileTypeMap: {
        idFront: "身份证（正面）",
        idBack: "身份证（反面）",
        photo: "证件照",
        application: "申请表",
        education: "学历证明",
        medical: "体检报告"
      },
      previewVisible: false,
      previewImg: '',
      fileData: [],
      currentIndex: 0,
      debugMode: false,
      imageLoaded: {},
      baseFileUrl: 'http://127.0.0.1:9300',
      operationType: 'add',
      replaceFileIdx: -1,
      lastModifiedFileId: null,
      duplicateUrlDialogVisible: false,
      urlUsageMap: {}
    };
  },
  computed: {
    // 弹窗显示状态（双向绑定）
    dialogVisible: {
      get() {
        return this.visible;
      },
      set(val) {
        this.$emit('update:visible', val);
        if (!val) {
          this.$emit('close');
        }
      }
    },
    currentFiles() {
      return (this.fileData[this.currentIndex] && this.fileData[this.currentIndex].files) || [];
    },
    // 当前用户的备注
    currentRemark: {
      get() {
        return (this.fileData[this.currentIndex] && this.fileData[this.currentIndex].remark) || '';
      },
      set(val) {
        if (this.fileData[this.currentIndex]) {
          this.$set(this.fileData[this.currentIndex], 'remark', val);
        }
      }
    },
    selectedTypeList() {
      if (!this.fileData.length) return [];
      return [...new Set(this.currentFiles.map(f => f.type))].filter(type => type);
    },
    selectedTypeCount() {
      return this.selectedTypeList.length;
    },
    totalTypeCount() {
      return Object.keys(this.fileTypeMap).length;
    },
    // 档案缺失情况取反：未选择的类型才勾选
    missingFiles() {
      if (!this.fileData.length) return {};
      const missing = {};
      Object.keys(this.fileTypeMap).forEach(typeKey => {
        // 未选择的类型标记为缺失
        missing[typeKey] = !this.selectedTypeList.includes(typeKey);
      });
      return missing;
    },
    // 提交按钮状态修改：不管是否上传文件都可提交，只检查重复URL
    canConfirm() {
      return !this.hasDuplicateUrls;
    },
    hasDuplicateUrls() {
      return Object.values(this.urlUsageMap).some(count => count > 1);
    }
  },
  watch: {
    visible: {
      immediate: true,
      handler(newVal) {
        if (newVal) {
          this.initFileData(this.userData);
          this.currentIndex = 0;
        } else {
          this.resetState();
        }
      }
    },
    userData: {
      deep: true,
      handler(newVal) {
        if (this.visible) {
          this.initFileData(newVal);
          this.currentIndex = 0;
        }
      }
    },
    currentIndex(newVal) {
      this.operationType = 'add';
      this.replaceFileIdx = -1;
      this.checkDuplicateUrls();
    },
    fileData: {
      deep: true,
      handler() {
        this.checkDuplicateUrls();
      }
    }
  },
  methods: {
    generateUniqueId() {
      return 'file_' + Date.now() + '_' + Math.floor(Math.random() * 1000000);
    },

    initFileData(data) {
      this.urlUsageMap = {};
      this.fileData = data.map((user, userIdx) => {
        const initFiles = user.urls.map((url, idx) => {
          const uniqueId = this.generateUniqueId();
          const fileUrl = url ? this.completeFileUrl(url) : '';

          // 从fileTypes获取初始类型
          const fileType = user.fileTypes && user.fileTypes[idx] ? user.fileTypes[idx] : '';

          if (fileUrl) {
            this.urlUsageMap[fileUrl] = (this.urlUsageMap[fileUrl] || 0) + 1;
          }

          if (fileUrl && this.isImage(fileUrl)) {
            this.imageLoaded[uniqueId] = false;
            const img = new Image();
            img.src = fileUrl;
            img.onload = () => {
              this.imageLoaded[uniqueId] = true;
              this.$forceUpdate();
            };
            img.onerror = () => {
              this.imageLoaded[uniqueId] = true;
              this.$forceUpdate();
            };
          } else {
            this.imageLoaded[uniqueId] = true;
          }

          return {
            uniqueId,
            url: fileUrl,
            name: this.getFileNameFromUrl(url),
            type: fileType,  // 使用fileTypes中的初始类型
            hasDuplicateUrl: false
          };
        });

        return {
          id: user.id,
          name: user.name,
          remark: user.remark || '',  // 存储用户备注
          files: initFiles,
          highlightedIdx: -1
        };
      });

      this.checkDuplicateUrls();
    },

    checkDuplicateUrls() {
      this.fileData.forEach(user => {
        if (user && user.files) {
          user.files.forEach(file => {
            file.hasDuplicateUrl = false;
          });
        }
      });

      this.urlUsageMap = {};
      this.fileData.forEach(user => {
        if (user && user.files) {
          user.files.forEach(file => {
            if (file.url && file.url.trim()) {
              this.urlUsageMap[file.url] = (this.urlUsageMap[file.url] || 0) + 1;
            }
          });
        }
      });

      let hasDuplicates = false;
      this.fileData.forEach(user => {
        if (user && user.files) {
          user.files.forEach(file => {
            if (file.url && file.url.trim() && this.urlUsageMap[file.url] > 1) {
              file.hasDuplicateUrl = true;
              hasDuplicates = true;
            }
          });
        }
      });

      if (hasDuplicates && !this.duplicateUrlDialogVisible) {
        this.duplicateUrlDialogVisible = true;
      }

      this.$forceUpdate();
    },

    triggerSingleUpload(fileIdx) {
      this.operationType = 'add';
      this.replaceFileIdx = fileIdx;
      this.lastModifiedFileId = this.currentFiles[fileIdx] && this.currentFiles[fileIdx].uniqueId;
      this.openUploadDialog(this.currentIndex);
    },

    handleReplaceSingle(fileIdx) {
      this.operationType = 'replace';
      this.replaceFileIdx = fileIdx;
      this.lastModifiedFileId = this.currentFiles[fileIdx] && this.currentFiles[fileIdx].uniqueId;
      if (this.fileData[this.currentIndex]) {
        this.fileData[this.currentIndex].highlightedIdx = fileIdx;
      }
      this.openUploadDialog(this.currentIndex);
    },

    openUploadDialog(userIdx) {
      try {
        const uploadRef = this.$refs[`fileUpload${userIdx}`];
        if (!uploadRef) {
          this.$message.error(`未找到用户${userIdx + 1}的上传组件`);
          return;
        }
        const innerUpload = uploadRef.$refs.fileUpload;
        if (!innerUpload) {
          this.$message.error('未找到内部上传控件');
          return;
        }
        const fileInput = innerUpload.$el.querySelector('input[type="file"]');
        if (fileInput) {
          fileInput.value = '';
          fileInput.removeAttribute('multiple');
          fileInput.click();
        } else {
          this.$message.error('无法找到文件上传控件');
        }
      } catch (error) {
        this.$message.error(`上传触发失败: ${error.message}`);
        console.error('上传触发错误:', error);
      }
    },

    handleFileChange(fileStr, userIdx, targetFileIdx) {
      if (!fileStr || !this.fileData.length) return;

      const fileUrls = fileStr.split(',').filter(url => url.trim() && this.testUrlFormat(url));
      if (fileUrls.length === 0) {
        this.$message.warning('未获取到有效文件URL，请重新上传');
        return;
      }

      this.handleSingleFileUrl(fileUrls, userIdx, targetFileIdx);

      this.operationType = 'add';
      this.replaceFileIdx = -1;
      this.lastModifiedFileId = null;
      this.checkDuplicateUrls();
      this.$forceUpdate();
    },

    handleSingleFileUrl(fileUrls, userIdx, targetFileIdx) {
      if (targetFileIdx === -1 || !this.fileData[userIdx] || targetFileIdx >= this.fileData[userIdx].files.length) {
        this.$message.error('文件索引无效，无法更新文件');
        return;
      }

      const targetUrl = fileUrls[fileUrls.length - 1];
      this.processFileUrl(
        targetUrl,
        userIdx,
        targetFileIdx,
        this.operationType === 'replace'
      );

      if (fileUrls.length > 1) {
        this.$message.info(`检测到${fileUrls.length}个文件，仅为第${targetFileIdx + 1}个位置更新文件`);
      }
    },

    processFileUrl(rawUrl, userIdx, fileIdx, isReplace = false) {
      const newFileUrl = this.completeFileUrl(rawUrl);
      if (!this.testUrlFormat(newFileUrl)) {
        this.$message.error(`文件URL格式无效: ${newFileUrl}`);
        return;
      }

      const isDuplicate = this.checkUrlDuplicate(newFileUrl, userIdx, fileIdx);
      if (isDuplicate) {
        this.$message.warning('检测到重复的文件URL，可能导致显示异常');
      }

      const oldFile = this.fileData[userIdx] && this.fileData[userIdx].files[fileIdx];
      if (oldFile && oldFile.url) {
        if (this.urlUsageMap[oldFile.url] > 0) {
          this.urlUsageMap[oldFile.url]--;
          if (this.urlUsageMap[oldFile.url] === 0) {
            delete this.urlUsageMap[oldFile.url];
          }
        }
        if (oldFile.uniqueId) {
          delete this.imageLoaded[oldFile.uniqueId];
        }
      }

      const uniqueId = this.generateUniqueId();
      const newFile = {
        uniqueId,
        url: newFileUrl,
        name: this.getFileNameFromUrl(rawUrl),
        type: isReplace && oldFile ? oldFile.type : '',  // 替换时保留原类型
        hasDuplicateUrl: isDuplicate
      };

      this.urlUsageMap[newFileUrl] = (this.urlUsageMap[newFileUrl] || 0) + 1;

      if (this.fileData[userIdx]) {
        this.$set(this.fileData[userIdx].files, fileIdx, newFile);
      }

      this.imageLoaded[uniqueId] = false;
      if (this.isImage(newFileUrl)) {
        const img = new Image();
        img.src = newFileUrl;
        img.onload = () => {
          this.imageLoaded[uniqueId] = true;
          this.$forceUpdate();
        };
        img.onerror = () => {
          this.imageLoaded[uniqueId] = true;
          this.$forceUpdate();
        };
      } else {
        this.imageLoaded[uniqueId] = true;
      }
    },

    handleImageLoad(uniqueId) {
      this.imageLoaded[uniqueId] = true;
      this.$forceUpdate();
    },

    handleImageError(uniqueId) {
      this.imageLoaded[uniqueId] = true;
      for (let i = 0; i < this.fileData.length; i++) {
        const user = this.fileData[i];
        if (user && user.files) {
          const fileIdx = user.files.findIndex(f => f.uniqueId === uniqueId);
          if (fileIdx !== -1) {
            const errorPlaceholder = '';
            const oldUrl = user.files[fileIdx].url;
            if (oldUrl && this.urlUsageMap[oldUrl] > 0) {
              this.urlUsageMap[oldUrl]--;
              if (this.urlUsageMap[oldUrl] === 0) {
                delete this.urlUsageMap[oldUrl];
              }
            }
            this.$set(user.files, fileIdx, {
              ...user.files[fileIdx],
              url: errorPlaceholder,
              hasDuplicateUrl: this.checkUrlDuplicate(errorPlaceholder, i, fileIdx)
            });
            this.urlUsageMap[errorPlaceholder] = (this.urlUsageMap[errorPlaceholder] || 0) + 1;
            break;
          }
        }
      }
      this.checkDuplicateUrls();
      this.$forceUpdate();
    },

    completeFileUrl(url) {
      if (!url || url.trim() === '') return '';
      if (url.startsWith('http://') || url.startsWith('https://')) {
        return url;
      }
      return `${this.baseFileUrl}${url.startsWith('/') ? '' : '/'}${url}`;
    },

    handleDeleteSingle(fileIdx) {
      this.$confirm(`确定要删除第${fileIdx + 1}个文件吗？`, '确认删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const userIdx = this.currentIndex;
        const user = this.fileData[userIdx];
        if (!user || !user.files) return;

        const oldFile = user.files[fileIdx];

        delete this.imageLoaded[oldFile.uniqueId];
        if (oldFile.url && this.urlUsageMap[oldFile.url] > 0) {
          this.urlUsageMap[oldFile.url]--;
          if (this.urlUsageMap[oldFile.url] === 0) {
            delete this.urlUsageMap[oldFile.url];
          }
        }

        const uniqueId = this.generateUniqueId();
        this.imageLoaded[uniqueId] = true;
        const emptyFile = {
          uniqueId,
          url: '',
          name: '',
          type: '',
          hasDuplicateUrl: false
        };

        this.$set(user.files, fileIdx, emptyFile);
        user.highlightedIdx = -1;

        const uploadRef = this.$refs[`fileUpload${userIdx}`];
        if (uploadRef && uploadRef.$refs.fileUpload) {
          const fileInput = uploadRef.$refs.fileUpload.$el.querySelector('input[type="file"]');
          if (fileInput) fileInput.value = '';
        }

        this.checkDuplicateUrls();
        this.$forceUpdate();
        this.$message.success('文件已删除');
      });
    },

    handleTypeSelect(fileIdx, typeKey) {
      const targetUser = this.fileData[this.currentIndex];
      if (!targetUser || !targetUser.files) return;

      targetUser.files.forEach((file, idx) => {
        if (file.type === typeKey && idx !== fileIdx) {
          this.$set(file, 'type', '');
        }
      });

      this.$set(targetUser.files[fileIdx], 'type', typeKey);
      targetUser.highlightedIdx = fileIdx;
      this.$forceUpdate();
    },

    isTypeUsed(typeKey, currentFileIdx) {
      return this.currentFiles.some((file, idx) => {
        return file.type === typeKey && idx !== currentFileIdx;
      });
    },

    handlePrev() {
      if (this.currentIndex > 0) {
        this.currentIndex--;
        this.scrollToTop();
      }
    },

    handleNext() {
      if (this.currentIndex < this.fileData.length - 1) {
        this.currentIndex++;
        this.scrollToTop();
      }
    },

    scrollToTop() {
      const container = this.$el.querySelector('.dialog-content');
      if (container) container.scrollTop = 0;
    },

    handlePreviewImg(url) {
      if (!url || !this.testUrlFormat(url)) {
        this.$message.error('文件地址无效，无法预览');
        return;
      }
      this.previewImg = url;
      this.previewVisible = true;
    },

    getFileNameFromUrl(url) {
      if (!url || url.trim() === '') return '';
      const pureUrl = url.split('?')[0];
      return pureUrl.split('/').pop() || '';
    },

    getFileName(name) {
      if (!name) return '';
      const match = name.match(/_(\w+\.\w+)$/);
      return match ? match[1] : name;
    },

    getFileExtension(url) {
      if (!url || url.trim() === '') return '';
      const pureUrl = url.split('?')[0];
      const ext = pureUrl.split('.').pop().toLowerCase();
      return ext || '';
    },

    isImage(url) {
      if (!url || url.trim() === '') return false;
      const imgExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'jfif', 'svg'];
      const ext = this.getFileExtension(url);
      return imgExts.includes(ext);
    },

    testUrlFormat(url) {
      try {
        new URL(url);
        return true;
      } catch (e) {
        console.error('无效URL格式:', url);
        return false;
      }
    },

    checkUrlDuplicate(newUrl, userIdx, fileIdx) {
      return this.fileData.some((user, uIdx) => {
        if (!user || !user.files) return false;
        return user.files.some((file, fIdx) => {
          if (uIdx === userIdx && fIdx === fileIdx) return false;
          return file.url === newUrl;
        });
      });
    },

    listToString(files, userIdx) {
      if (!Array.isArray(files) || !files.length) return '';

      if (this.operationType === 'replace' && this.replaceFileIdx !== -1) {
        const targetFile = files[this.replaceFileIdx];
        return targetFile.url && targetFile.url.trim() ? targetFile.url : '';
      }

      return files.map(file => file.url).filter(url => url && url.trim()).join(',');
    },

    handleUploadSuccess(userIdx) {
      const user = this.fileData[userIdx];
      if (user) {
        this.$message.success(`用户ID ${user.id} 的文件上传成功`);
      }
    },

    handleSingleConfirm(userIdx) {
      if (this.hasDuplicateUrls) {
        this.duplicateUrlDialogVisible = true;
        return;
      }

      const currentUser = this.fileData[userIdx];
      if (!currentUser) return;

console.log(this.registrationId)
      const singleSubmitData = {
        allUsersData: [{
          userId: currentUser.id,
          remark: currentUser.remark,  // 提交备注信息
          fileUnits: currentUser.files
            .map(file => ({  // 不再过滤空文件，全部提交
              uniqueId: file.uniqueId,
              url: file.url,
              fileName: file.name,
              fileType: file.type || '未分类',
              fileTypeName: this.fileTypeMap[file.type] || '未分类'
            })),
          missingTypes: Object.keys(this.missingFiles).filter(key => this.missingFiles[key])
        }],
        registrationId:this.registrationId
      };

      this.$emit('single-confirm', singleSubmitData);
      this.$message.success(`已成功提交用户ID【${currentUser.id}】的档案！`);
    },

    handleBeforeClose() {
      this.dialogVisible = false;
    },

    resetState() {
      this.previewVisible = false;
      this.previewImg = '';
      this.fileData = [];
      this.currentIndex = 0;
      this.imageLoaded = {};
      this.operationType = 'add';
      this.replaceFileIdx = -1;
      this.lastModifiedFileId = null;
      this.duplicateUrlDialogVisible = false;
      this.urlUsageMap = {};
    },

    onConfirm() {
      if (this.hasDuplicateUrls) {
        this.duplicateUrlDialogVisible = true;
        return;
      }
      const submitData = {
        allUsersData: this.fileData.map(user => ({
          userId: user.id,
          remark: user.remark,  // 提交备注信息
          fileUnits: user.files.map(file => ({  // 不再过滤空文件，全部提交
            uniqueId: file.uniqueId,
            url: file.url,
            fileName: file.name,
            fileType: file.type || '未分类',
            fileTypeName: this.fileTypeMap[file.type] || '未分类'
          })),
          missingTypes: Object.keys(this.missingFiles).filter(key => this.missingFiles[key])
        })),
        registrationId:this.registrationId
      };

      this.$emit('confirm', submitData);
      this.$message.success('全部档案提交成功！');
      this.handleBeforeClose();
    }
  }
};
</script>

<style scoped lang="scss">
// 基础变量
$primary-color: #409eff;
$success-color: #67c23a;
$warning-color: #ff9800;
$danger-color: #f56c6c;
$gray-light: #f5f7fa;
$gray-medium: #e9ecef;
$gray-dark: #86909c;
$text-main: #1f2329;
$border-radius: 6px;
$shadow-light: 0 2px 8px rgba(0, 0, 0, 0.08);

// Dialog 内容区容器
.dialog-content {
  max-height: 60vh;
  overflow-y: auto;
  padding: 10px 0;
}

// 个人信息样式
.personal-info {
  padding: 0 10px 16px;
  border-bottom: 1px solid $gray-medium;
  font-size: 14px;
  color: $text-main;

  .user-index {
    color: $gray-dark;
    margin-right: 8px;
  }

  .user-id {
    font-weight: 500;
  }
}

// 档案预览区域
.file-preview {
  padding: 16px 10px;

  .file-item {
    margin-bottom: 20px;
    padding-bottom: 20px;
    border-bottom: 1px dashed $gray-medium;

    &:last-child {
      border-bottom: none;
    }
  }

  .file-content-with-actions {
    display: flex;
    align-items: flex-start;
    gap: 20px;
  }

  .file-content {
    flex: 1;
  }
}

// 预览容器
.preview-container {
  width: 100%;
  border: 1px solid $gray-medium;
  border-radius: $border-radius;
  overflow: hidden;
  margin-bottom: 16px;
  transition: all 0.2s;
  background-color: #fff;

  &.selected {
    border-color: $primary-color;
    box-shadow: 0 0 0 2px rgba($primary-color, 0.1);
  }

  &.duplicate-url {
    border-color: $warning-color;
    position: relative;

    &::before {
      content: "⚠️ 重复文件URL";
      position: absolute;
      top: 8px;
      right: 8px;
      background-color: $warning-color;
      color: white;
      font-size: 12px;
      padding: 2px 8px;
      border-radius: 4px;
      z-index: 5;
    }
  }
}

// 调试信息
.debug-info {
  display: none;
  font-size: 12px;
  color: $gray-dark;
  padding: 8px 16px;
  background-color: rgba($warning-color, 0.05);

  .duplicate-warning {
    color: $danger-color;
    margin-left: 8px;
    font-weight: 500;
  }
}

// 文件预览区
.file-preview-area {
  padding: 16px;
  background-color: $gray-light;
  position: relative;

  &.second-file {
    min-height: 160px;
  }
}

.single-preview-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

// 预览媒体容器
.preview-media {
  flex: 1;
  min-width: 240px;
  height: 160px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #fff;
  border: 1px solid $gray-medium;
  border-radius: $border-radius;
  cursor: pointer;
  overflow: hidden;
  position: relative;
}

// 图片预览
.preview-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: all 0.3s;

  &:hover {
    transform: scale(1.02);
  }
}

// 文档预览
.doc-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: $gray-dark;

  .doc-icon {
    font-size: 40px;
    color: $primary-color;
    margin-bottom: 10px;
  }

  .doc-info {
    text-align: center;

    .doc-name {
      font-size: 12px;
      color: $text-main;
      max-width: 180px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .doc-ext {
      font-size: 11px;
      color: $gray-dark;
      margin-top: 3px;
    }
  }
}

// 空预览
.empty-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: $gray-dark;
  border: 2px dashed $gray-medium;
  border-radius: $border-radius;
  cursor: pointer;
  transition: all 0.2s;

  &:hover {
    border-color: $primary-color;
    color: $primary-color;
    background-color: rgba($primary-color, 0.02);
  }

  .upload-icon {
    font-size: 28px;
    margin-bottom: 10px;
  }

  .empty-tip {
    font-size: 13px;
    margin: 0 0 3px 0;
    font-weight: 500;
  }

  .empty-subtip {
    font-size: 11px;
    margin: 0;
    color: $gray-dark;
  }
}

// 加载中
.preview-loading {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 10;

  .el-icon-loading {
    font-size: 22px;
    color: $primary-color;
  }

  .loading-tip {
    margin-top: 10px;
    font-size: 12px;
    color: $gray-dark;
  }
}

// 操作按钮
.single-file-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.small-btn {
  width: 32px;
  height: 32px;
  padding: 0;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: $border-radius;
  cursor: pointer;
  border: 1px solid transparent;
  transition: all 0.2s;

  &.delete-single-btn {
    background-color: rgba($danger-color, 0.05);
    color: $danger-color;
    border-color: rgba($danger-color, 0.2);

    &:hover {
      background-color: rgba($danger-color, 0.1);
      border-color: rgba($danger-color, 0.3);
    }
  }

  &.replace-single-btn {
    background-color: rgba($success-color, 0.05);
    color: $success-color;
    border-color: rgba($success-color, 0.2);

    &:hover {
      background-color: rgba($success-color, 0.1);
      border-color: rgba($success-color, 0.3);
    }
  }
}

// 类型选择
.type-radio-container {
  padding: 12px 16px;
  background-color: #fff;
  border-top: 1px solid $gray-medium;

  &.disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  .radio-group-title {
    margin: 0 0 10px 0;
    font-size: 12px;
    color: $gray-dark;
    font-weight: 500;
  }
}

.type-radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.radio-label {
  display: inline-flex;
  align-items: center;
  padding: 5px 14px;
  background-color: #fff;
  border: 1px solid $gray-medium;
  border-radius: 20px;
  color: $text-main;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.2s;

  &.selected {
    background-color: $primary-color;
    color: white;
    border-color: $primary-color;
  }

  &.disabled {
    opacity: 0.6;
    cursor: not-allowed;
    background-color: $gray-light;
  }

  .radio-input {
    margin-right: 5px;
    width: 13px;
    height: 13px;
    accent-color: $primary-color;
  }

  .radio-text {
    user-select: none;
  }
}

// 单人提交按钮
.single-user-confirm {
  margin-top: 16px;
  padding: 8px 16px;
  border-top: 1px dashed $gray-medium;

  .btn.confirm-btn {
    padding: 7px 20px;
    font-size: 13px;
  }
}

// 缺失情况
.missing-files {
  padding: 16px 10px;
  border-top: 1px solid $gray-medium;

  .missing-title {
    margin: 0 0 12px 0;
    font-size: 13px;
    color: $text-main;
    font-weight: 500;
  }

  .missing-checkboxes {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
  }

  .file-checkbox {
    display: flex;
    align-items: center;
    font-size: 12px;
    color: $text-main;
    cursor: default;

    .checkbox-input {
      margin-right: 5px;
      width: 13px;
      height: 13px;
      accent-color: $danger-color;
    }

    .checkbox-text {
      display: flex;
      align-items: center;

      .missing-tag {
        color: $danger-color;
        font-weight: 500;
      }

      .missing-text {
        margin-left: 3px;
        color: $danger-color;
        font-size: 11px;
      }
    }
  }
}

// 备注区域
.remarks {
  padding: 16px 10px;
  border-top: 1px solid $gray-medium;

  .remarks-label {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    color: $text-main;
    font-weight: 500;
  }

  .remarks-input {
    width: 100%;
    min-height: 70px;
    border: 1px solid $gray-medium;
    border-radius: $border-radius;
    padding: 10px 14px;
    resize: vertical;
    font-size: 12px;
    box-sizing: border-box;
    transition: border-color 0.2s;
    font-family: inherit;

    &:focus {
      outline: none;
      border-color: $primary-color;
      box-shadow: 0 0 0 2px rgba($primary-color, 0.1);
    }

    &::placeholder {
      color: $gray-dark;
    }
  }
}

// Dialog 底部按钮
.dialog-footer-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}

// 通用按钮样式
.btn {
  padding: 7px 16px;
  border-radius: $border-radius;
  border: 1px solid transparent;
  cursor: pointer;
  font-size: 13px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: all 0.2s;
  font-weight: 500;

  &:disabled {
    opacity: 0.7;
    cursor: not-allowed;
    background-color: $gray-light;
    border-color: $gray-medium;
    color: $gray-dark;
  }

  &.prev-btn,
  &.next-btn {
    background-color: #fff;
    color: $text-main;
    border-color: $gray-medium;

    &:hover:not(:disabled) {
      background-color: $gray-light;
      border-color: $gray-dark;
    }
  }

  &.cancel-btn {
    background-color: #fff;
    color: $text-main;
    border-color: $gray-medium;

    &:hover:not(:disabled) {
      background-color: $gray-light;
    }
  }

  &.confirm-btn {
    background-color: $primary-color;
    color: white;
    border-color: $primary-color;

    &:hover:not(:disabled) {
      background-color: #3688e6;
      border-color: #3688e6;
    }

    &:disabled {
      background-color: rgba($primary-color, 0.3);
      border-color: rgba($primary-color, 0.3);
    }
  }
}

// 图片预览弹窗
.preview-dialog {
  .el-dialog__body {
    padding: 12px;
  }
}

.preview-modal-content {
  width: 100%;
  padding: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #fafafa;
  border-radius: $border-radius;
}

.preview-modal-img {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
  border-radius: $border-radius;
  box-shadow: $shadow-light;
}

// 重复URL弹窗
.duplicate-dialog {
  .el-dialog__body {
    padding: 16px;
  }
}

.duplicate-url-message {
  font-size: 13px;
  line-height: 1.6;
  color: $text-main;

  .message-line {
    margin-bottom: 10px;
  }

  .message-list {
    margin: 0 0 0 18px;
    padding: 0;

    .list-item {
      margin-bottom: 6px;
      color: $gray-dark;
      font-size: 12px;
    }
  }
}

// 隐藏上传组件
.hidden-upload {
  display: none;
}

// 滚动条美化
.dialog-content::-webkit-scrollbar,
.file-preview::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}

.dialog-content::-webkit-scrollbar-track,
.file-preview::-webkit-scrollbar-track {
  background: $gray-light;
  border-radius: 3px;
}

.dialog-content::-webkit-scrollbar-thumb,
.file-preview::-webkit-scrollbar-thumb {
  background: $gray-dark;
  border-radius: 3px;
  opacity: 0.5;
}

.dialog-content::-webkit-scrollbar-thumb:hover,
.file-preview::-webkit-scrollbar-thumb:hover {
  opacity: 0.8;
}

// 响应式适配
@media (max-width: 768px) {
  .dialog-content {
    max-height: 50vh;
  }

  .preview-media {
    min-width: 100%;
  }

  .single-preview-item {
    flex-direction: column;
    align-items: flex-start;
  }

  .single-file-actions {
    align-self: flex-end;
  }

  .dialog-footer-actions {
    justify-content: center;
  }

  .single-user-confirm {
    justify-content: center;

    .btn.confirm-btn {
      width: 100%;
    }
  }
}
</style>
